package com.gitee.xmhzzz.component.swagger;

import com.gitee.xmhzzz.component.swagger.plugin.SwaggerPluginConfiguration;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import springfox.bean.validators.configuration.BeanValidatorPluginsConfiguration;
import springfox.documentation.RequestHandler;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.oas.annotations.EnableOpenApi;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger.web.UiConfiguration;
import springfox.documentation.swagger.web.UiConfigurationBuilder;

import com.google.common.base.Function;
import com.google.common.base.Optional;

import java.util.function.Predicate;

/**
  * @ClassName
  * @Description
  * @Author wzq
  * @Date 2023/12/18 10:23
  * @Version 1.0
  */
@EnableOpenApi
@Configuration
@Import({BeanValidatorPluginsConfiguration.class, SwaggerPluginConfiguration.class})
public class SwaggerConfiguration
{
    //是否开启swagger，正式环境一般是需要关闭的，可根据springboot的多环境配置进行设置
    @Value(value = "${swagger.internalEnabled:false}")
    Boolean internalEnabled;

    @Value(value = "${swagger.internalApiPackage:''}")
    String internalApiPackage;

    @Value(value = "${swagger.internalApiGroupName:'default'}")
    String internalApiGroupName;

    //是否开启swagger，正式环境一般是需要关闭的，可根据springboot的多环境配置进行设置
    @Value(value = "${swagger.enabled:false}")
    Boolean swaggerEnabled;

    @Value(value = "${swagger.restfulApiPackage:''}")
    String restfulApiPackage;

    @Value(value = "${swagger.restfulApiGroupName:'restfulDefault'}")
    String restfulApiGroupName;

    @Value(value = "${swagger.title:'xmh服务'}")
    String restfulTitle;

    @Value(value = "${swagger.name:'xmh'}")
    String name;

    @Value(value = "${swagger.mail:'xmh@qq.com'}")
    String mail;

    // 定义分隔符
    private static final String splitor = ",";

    @Bean
    public Docket createRestApi() {

        return new Docket(DocumentationType.OAS_30)
                .apiInfo(apiInfo()).groupName(internalApiGroupName)
                // 是否开启
                .enable(internalEnabled).select()
                // 扫描的路径包
                .apis(basePackage(internalApiPackage))
                // 指定路径处理PathSelectors.any()代表所有的路径
                .paths(PathSelectors.any())
                .build().pathMapping("/");
    }



    @Bean
    public Docket createAdminApi() {

       return new Docket(DocumentationType.OAS_30)
                .apiInfo(apiInfo()).groupName(restfulApiGroupName)
                // 是否开启
                .enable(swaggerEnabled).select()
                // 扫描的路径包
                .apis(basePackage(restfulApiPackage))
                // 指定路径处理PathSelectors.any()代表所有的路径
                .paths(PathSelectors.any()).build().pathMapping("/");
    }



    @Bean
    UiConfiguration uiConfig()
    {
        return UiConfigurationBuilder.builder().showExtensions(true).build();
    }


    private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                .title(restfulTitle)
                .description("")
                // 作者信息
                .contact(new Contact(name, "", mail))
                .version("1.0.0")
                .build();
    }


    public static Predicate<RequestHandler> basePackage(final String basePackage) {
        return input -> declaringClass(input).transform(handlerPackage(basePackage)).or(true);
    }
    private static Function<Class<?>, Boolean> handlerPackage(final String basePackage)     {
        return input -> {
            // 循环判断匹配
            for (String strPackage : basePackage.split(splitor)) {
                boolean isMatch = input.getPackage().getName().startsWith(strPackage);
                if (isMatch) {
                    return true;
                }
            }
            return false;
        };
    }
    private static Optional<? extends Class<?>> declaringClass(RequestHandler input) {
        return Optional.fromNullable(input.declaringClass());
    }



}
